﻿using IdentityModel;
using IdentityServer4.Extensions;
using IdentityServer4.Models;
using IdentityServer4.Services;
using JX.Application;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace JXIdentityServer
{
	public class CustomProfileService : IProfileService
	{
		private IAdminServiceApp _AdminService;
		protected readonly ILogger Logger;
		/// <summary>
		/// 构造器注入
		/// </summary>
		/// <param name="adminService"></param>
		/// <param name="logger"></param>
		public CustomProfileService(IAdminServiceApp adminService, ILogger<CustomProfileService> logger)
		{
			_AdminService = adminService;
			Logger = logger;
		}

		/// <summary>
		/// 只要有关用户的身份信息单元被请求（例如在令牌创建期间或通过用户信息终点），就会调用此方法
		/// </summary>
		/// <param name="context"></param>
		/// <returns></returns>
		public virtual Task GetProfileDataAsync(ProfileDataRequestContext context)
		{
			context.LogProfileRequest(Logger);

			//判断是否有请求Claim信息
			if (context.RequestedClaimTypes.Any())
			{
				//根据用户唯一标识查找用户信息
				var adminEntity = _AdminService.Get(p => p.AdminID.ToString() == context.Subject.GetSubjectId());
				if (adminEntity != null)
				{
					//调用此方法以后内部会进行过滤，只将用户请求的Claim加入到 context.IssuedClaims 集合中 这样我们的请求方便能正常获取到所需Claim
					var claimsPrincipal = _AdminService.CreateClaimsIdentity(adminEntity);
					var claims = new Claim[] {
							new Claim(JwtClaimTypes.Id,claimsPrincipal.FindFirst(ClaimTypes.Sid).Value)
							,new Claim(JwtClaimTypes.Name,claimsPrincipal.FindFirst(ClaimTypes.Name).Value)
							,new Claim(JwtClaimTypes.Role,claimsPrincipal.FindFirst(ClaimTypes.Role).Value)
						};
					context.AddRequestedClaims(claims);
				}
			}

			context.LogIssuedClaims(Logger);

			return Task.CompletedTask;
		}

		/// <summary>
		/// 验证用户是否有效 例如：token创建或者验证
		/// </summary>
		/// <param name="context">The context.</param>
		/// <returns></returns>
		public virtual Task IsActiveAsync(IsActiveContext context)
		{
			Logger.LogDebug("IsActive called from: {caller}", context.Caller);

			//根据用户唯一标识查找用户信息
			var adminEntity = _AdminService.Get(p => p.AdminID.ToString() == context.Subject.GetSubjectId());
			context.IsActive = adminEntity?.IsLock == false;

			return Task.CompletedTask;
		}
	}
}
